﻿#include "ReportGenerator.h"
#include <QWidget>
#include <QTableWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFileDialog>
#include <QMessageBox>
#include <QStandardPaths>
#include <QMenuBar>
#include <QMenu>
#include <QStatusBar>
#include <QHeaderView>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <windows.h>

ReportGenerator::ReportGenerator(QWidget *parent)
    : QWidget{parent}
    ,m_tableWidget(new QTableWidget(this)){
    setupTable();
}

ReportGenerator::~ReportGenerator()
{
}

QTableWidget* ReportGenerator::getTableWidgetPtr(){
    return m_tableWidget;
}
void ReportGenerator::setupTable(){
    m_tableWidget->setColumnCount(4);
    m_tableWidget->setHorizontalHeaderLabels(QStringList() << "点位" << "微分干涉" << "亮点" << "暗场");
    m_tableWidget->setRowCount(13);
    m_tableWidget->verticalHeader()->setVisible(false);//隐藏行头

    // 填充第一列点位编号（从1开始，居中显示）
    for (int row = 0; row < 13; ++row) {
        QTableWidgetItem *item = new QTableWidgetItem(QString::number(row + 1));
        item->setTextAlignment(Qt::AlignCenter); // 设置文本居中
        m_tableWidget->setItem(row, 0, item);
    }
    // 设置表格属性
    m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); // 整行选择
    m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);  // 不可编辑
    m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    m_tableWidget->setAlternatingRowColors(true);
}

void ReportGenerator::setCurPoint(const int &point){
    m_curPoint = point;
}

void ReportGenerator::setData(const QJsonObject &obj){
    if(m_curPoint == 0){
        QMessageBox::warning(nullptr,"警告","请先选择点位");
        return;
    }

    // 检查JSON对象是否包含必要的字段
    if (!obj.contains("types") || !obj.contains("data")) {
        QMessageBox::warning(nullptr, "错误", "JSON数据缺少必要字段(types或data)");
        return;
    }

    // 获取types值
    int types = obj["types"].toInt();

    // 获取data对象
    QJsonObject dataObj = obj["data"].toObject();

    // 检查data对象是否包含quantity字段
    if (!dataObj.contains("quantity")) {
        QMessageBox::warning(nullptr, "错误", "JSON数据缺少quantity字段");
        return;
    }

    // 获取quantity值
    double quantity = dataObj["quantity"].toDouble();

    // 根据types值将quantity填充到对应列
    QTableWidgetItem *valueItem = new QTableWidgetItem(QString::number(quantity, 'f', 2));
    valueItem->setTextAlignment(Qt::AlignCenter); // 设置文本居中
    //行数
    auto RowIndex = m_curPoint - 1;
    //写入数据
    switch (types) {
    case 1: // 微分干涉
        m_tableWidget->setItem(RowIndex, 1, valueItem);
        break;
    case 2: // 亮点
        m_tableWidget->setItem(RowIndex, 2, valueItem);
        break;
    case 3: // 暗场
        m_tableWidget->setItem(RowIndex, 3, valueItem);
        break;
    default:
        delete valueItem; // 删除未使用的item
        QMessageBox::warning(nullptr, "错误", "未知的types值");
        break;
    }
}

void ReportGenerator::generateReport()
{
    QString fileName = QFileDialog::getSaveFileName(this, "保存报告",
                                                    QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
                                                    "Word文档 (*.docx *.doc)");
    if (fileName.isEmpty())
        return;
    if (generateWordReport(fileName)) {
        QMessageBox::information(this, "成功", "报告已生成: " + fileName);
    } else {
        QMessageBox::critical(this, "错误", "生成报告时发生错误。请确保已安装Microsoft Word。");
    }
}

bool ReportGenerator::generateWordReport(const QString &fileName)
{
    try {
        // 初始化COM库（如果之前没有初始化）
        CoInitialize(NULL);

        // 创建Word应用程序对象
        QAxObject *word = new QAxObject("Word.Application");
        if (word->isNull()) {
            QMessageBox::warning(nullptr, "错误", "无法启动Word应用程序，请确保已安装Microsoft Word");
            delete word;
            return false;
        }

        // 设置Word不可见
        word->setProperty("Visible", false);

        // 获取文档集合
        QAxObject *documents = word->querySubObject("Documents");
        if (documents->isNull()) {
            word->dynamicCall("Quit()");
            delete word;
            QMessageBox::warning(nullptr, "错误", "无法访问Word文档集合");
            return false;
        }

        // 添加新文档
        QAxObject *document = documents->querySubObject("Add()");
        if (document->isNull()) {
            word->dynamicCall("Quit()");
            delete word;
            QMessageBox::warning(nullptr, "错误", "无法创建新文档");
            return false;
        }

        // 获取选区对象
        QAxObject *selection = word->querySubObject("Selection");
        if (selection->isNull()) {
            document->dynamicCall("Close(false)");
            word->dynamicCall("Quit()");
            delete word;
            QMessageBox::warning(nullptr, "错误", "无法访问Word选择对象");
            return false;
        }

        // 添加标题
        QAxObject *paragraphFormat = selection->querySubObject("ParagraphFormat");
        paragraphFormat->setProperty("Alignment", 1); // 居中

        QAxObject *font = selection->querySubObject("Font");
        font->setProperty("Size", 16);
        font->setProperty("Bold", true);
        font->setProperty("Name", "微软雅黑");

        selection->dynamicCall("TypeText(const QString&)", "项目测试报告");
        selection->dynamicCall("TypeParagraph()");

        // 添加自定义报告信息
        paragraphFormat->setProperty("Alignment", 0); // 左对齐
        font->setProperty("Size", 12);
        font->setProperty("Bold", false);

        // 添加Platen编号
        selection->dynamicCall("TypeText(const QString&)", "Platen编号: " + m_reportInfo.PlatenNumber);
        selection->dynamicCall("TypeParagraph()");

        // 添加外延编号
        selection->dynamicCall("TypeText(const QString&)", "外延编号: " + m_reportInfo.WY_Number);
        selection->dynamicCall("TypeParagraph()");

        // 添加结构类型
        selection->dynamicCall("TypeText(const QString&)", "结构类型: " + m_reportInfo.structureType);
        selection->dynamicCall("TypeParagraph()");

        // 添加衬底编号
        selection->dynamicCall("TypeText(const QString&)", "衬底编号: " + m_reportInfo.CD_Number);
        selection->dynamicCall("TypeParagraph()");

        // 添加测试人信息
        selection->dynamicCall("TypeText(const QString&)", "测试人员: " + m_reportInfo.tester);
        selection->dynamicCall("TypeParagraph()");


        // 添加测试日期
        selection->dynamicCall("TypeText(const QString&)", "测试日期: " + m_reportInfo.testDate.toString("yyyy年MM月dd日"));
        selection->dynamicCall("TypeParagraph()");

        // 添加空行
        selection->dynamicCall("TypeParagraph()");

        // 添加生成时间
        QString dateStr = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        selection->dynamicCall("TypeText(const QString&)", "报告生成时间: " + dateStr);
        selection->dynamicCall("TypeParagraph()");
        selection->dynamicCall("TypeParagraph()");

        // 添加表格标题
        font->setProperty("Bold", true);
        selection->dynamicCall("TypeText(const QString&)", "测试数据表格:");
        selection->dynamicCall("TypeParagraph()");
        font->setProperty("Bold", false);

        // 创建表格
        int rowCount = m_tableWidget->rowCount();
        int colCount = m_tableWidget->columnCount();

        // 获取当前选区范围
        QAxObject *range = selection->querySubObject("Range");
        QAxObject *tables = document->querySubObject("Tables");

        // 创建表格 (行数+1是为了表头行)
        QAxObject *table = tables->querySubObject("Add(Range, NumRows, NumColumns)",
                                                  range->asVariant(), rowCount + 1, colCount);

        if (table->isNull()) {
            document->dynamicCall("Close(false)");
            word->dynamicCall("Quit()");
            delete word;
            QMessageBox::warning(nullptr, "错误", "无法创建表格");
            return false;
        }

        // 设置表格样式
        table->setProperty("Style", "网格表");

        // 设置表头
        for (int col = 0; col < colCount; ++col) {
            QAxObject *cell = table->querySubObject("Cell(Row, Column)", 1, col + 1);
            QAxObject *cellRange = cell->querySubObject("Range");

            QString headerText = m_tableWidget->horizontalHeaderItem(col) ?
                                     m_tableWidget->horizontalHeaderItem(col)->text() :
                                     QString("列 %1").arg(col + 1);

            cellRange->setProperty("Text", headerText);

            QAxObject *cellFont = cellRange->querySubObject("Font");
            cellFont->setProperty("Bold", true);
            cellFont->setProperty("Size", 11);
        }

        // 填充表格数据
        for (int row = 0; row < rowCount; ++row) {
            for (int col = 0; col < colCount; ++col) {
                QTableWidgetItem *item = m_tableWidget->item(row, col);
                QString text = item ? item->text() : "";

                QAxObject *cell = table->querySubObject("Cell(Row, Column)", row + 2, col + 1);
                QAxObject *cellRange = cell->querySubObject("Range");
                cellRange->setProperty("Text", text);

                // 设置数据单元格字体
                QAxObject *cellFont = cellRange->querySubObject("Font");
                cellFont->setProperty("Size", 10);
            }
        }

        // 移动到文档末尾
        selection->dynamicCall("EndKey(QVariant)", 6); // 6 = wdStory

        // 添加总结部分
        selection->dynamicCall("TypeParagraph()");
        selection->dynamicCall("TypeParagraph()");

        font->setProperty("Bold", true);
        font->setProperty("Size", 12);
        selection->dynamicCall("TypeText(const QString&)", "测试总结:");
        selection->dynamicCall("TypeParagraph()");

        // 添加测试结论
        font->setProperty("Bold", true);
        selection->dynamicCall("TypeText(const QString&)", "测试结论: ");
        font->setProperty("Bold", false);
        selection->dynamicCall("TypeText(const QString&)", "_________________________");
        selection->dynamicCall("TypeParagraph()");

        // 添加备注信息
        font->setProperty("Bold", true);
        selection->dynamicCall("TypeText(const QString&)", "备注: ");
        font->setProperty("Bold", false);
        selection->dynamicCall("TypeText(const QString&)", "_________________________");
        selection->dynamicCall("TypeParagraph()");

        // 添加空行
        selection->dynamicCall("TypeParagraph()");
        selection->dynamicCall("TypeParagraph()");

        // 添加签名区域
        font->setProperty("Bold", true);
        selection->dynamicCall("TypeText(const QString&)", "测试人员: _________________________");
        selection->dynamicCall("TypeParagraph()");
        selection->dynamicCall("TypeText(const QString&)", "审核人员: _________________________");
        selection->dynamicCall("TypeParagraph()");
        selection->dynamicCall("TypeText(const QString&)", "日期: _________________________");
        selection->dynamicCall("TypeParagraph()");

        // 保存文档
        QVariant fileNameVar(fileName);
        document->dynamicCall("SaveAs(const QVariant&)", fileNameVar);

        // 关闭文档
        document->dynamicCall("Close()");

        // 关闭Word应用程序
        word->dynamicCall("Quit()");

        // 释放资源
        delete table;
        delete tables;
        delete range;
        delete font;
        delete paragraphFormat;
        delete selection;
        delete document;
        delete documents;
        delete word;

        // 卸载COM库
        CoUninitialize();

        QMessageBox::information(nullptr, "成功", "报告已成功导出到: " + fileName);
        return true;
    } catch (const std::exception& e) {
        QMessageBox::critical(nullptr, "异常错误", QString("导出过程中发生异常: %1").arg(e.what()));
        return false;
    } catch (...) {
        QMessageBox::critical(nullptr, "未知错误", "导出过程中发生未知异常");
        return false;
    }

}

void ReportGenerator::setWordInfo(const QStringList &infos){
    m_wordInfo = infos;

    m_reportInfo.PlatenNumber = m_wordInfo[0];
    m_reportInfo.WY_Number = m_wordInfo[1];
    m_reportInfo.structureType = m_wordInfo[2];
    m_reportInfo.CD_Number = m_wordInfo[3];
    m_reportInfo.tester = m_wordInfo[4];
    m_reportInfo.testDate = QDate::currentDate();
}

void ReportGenerator::loadData()
{
    QString fileName = QFileDialog::getOpenFileName(this, "打开数据文件",
                                                    QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
                                                    "JSON文件 (*.json)");

    if (fileName.isEmpty())
        return;

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        QMessageBox::warning(this, "错误", "无法打开文件: " + fileName);
        return;
    }

    QByteArray data = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull() || !doc.isObject()) {
        QMessageBox::warning(this, "错误", "文件格式不正确");
        return;
    }

    QJsonObject root = doc.object();
    QJsonArray tableData = root["tableData"].toArray();

    if (tableData.isEmpty()) {
        QMessageBox::warning(this, "错误", "文件中没有有效数据");
        return;
    }

    // 清空表格
    m_tableWidget->setRowCount(0);

    // 设置列数
    if (tableData.size() > 0) {
        QJsonObject firstRow = tableData[0].toObject();
        m_tableWidget->setColumnCount(firstRow.size());

        // 设置表头
        QStringList headers;
        for (const QString &key : firstRow.keys()) {
            headers << key;
        }
        m_tableWidget->setHorizontalHeaderLabels(headers);
    }

    // 填充数据
    for (int i = 0; i < tableData.size(); ++i) {
        QJsonObject rowData = tableData[i].toObject();
        m_tableWidget->insertRow(i);

        int col = 0;
        for (const QString &key : rowData.keys()) {
            QTableWidgetItem *item = new QTableWidgetItem(rowData[key].toString());
            m_tableWidget->setItem(i, col, item);
            col++;
        }
    } 
}

void ReportGenerator::saveData()
{
    QString fileName = QFileDialog::getSaveFileName(this, "保存数据文件",
                                                    QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
                                                    "JSON文件 (*.json)");

    if (fileName.isEmpty())
        return;

    QJsonObject root;
    QJsonArray tableData;

    // 收集表格数据
    for (int row = 0; row < m_tableWidget->rowCount(); ++row) {
        QJsonObject rowData;
        for (int col = 0; col < m_tableWidget->columnCount(); ++col) {
            QString header = m_tableWidget->horizontalHeaderItem(col)->text();
            QTableWidgetItem *item = m_tableWidget->item(row, col);
            rowData[header] = item ? item->text() : "";
        }
        tableData.append(rowData);
    }

    root["tableData"] = tableData;
    root["saveDate"] = QDateTime::currentDateTime().toString(Qt::ISODate);

    QJsonDocument doc(root);
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly)) {
        QMessageBox::warning(this, "错误", "无法保存文件: " + fileName);
        return;
    }

    file.write(doc.toJson());
    file.close();
}
